package smecta.client.print.util.weight;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fazecast.jSerialComm.SerialPort;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import smecta.client.print.common.constants.ScaleConstant;
import smecta.client.print.common.exceptions.ServiceException;
import smecta.client.print.domain.ScpSysSettings;
import smecta.client.print.domain.weight.WeightSensorListenerContext;
import smecta.client.print.service.ScpSysSettingsService;
import smecta.client.print.service.cache.biz.SerialPortConnectionCacheService;

import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.Executor;

@Slf4j
@Component
public class WeightSensor {

    @Autowired
    private ScpSysSettingsService scpSysSettingsService;

    @Autowired
    @Qualifier(value = "scpExecutor")
    private Executor scpExecutor;

//    private SerialPort weightSensorComPort;
//
//    public SerialPort getWeightSensorComPort() {
//        return weightSensorComPort;
//    }

    private SerialPort get(String port){
        for (SerialPort sp:SerialPort.getCommPorts()){
            if(sp.getSystemPortName().contains(port)){
                return sp;
            }
        }
        throw new ServiceException("未找到串口:"+port);
    }

    public void refreshWeightSensor(String code, Object bean) {
        // 关闭历史连接
        close();

        // 加载最新配置
        Properties properties = loadFromDB();
        String port = properties.getProperty("port", "");
        String baudRate = properties.getProperty("baudRate", "9600");
        String dataBits = properties.getProperty("dataBits", "8");
        String regex = properties.getProperty("dataFlag", "ST,GS\\s+(\\d+(\\.\\d+)?)");
        SerialPort comPort = get(port);
        comPort.setBaudRate(Integer.valueOf(baudRate));
        comPort.setNumDataBits(Integer.valueOf(dataBits));
        comPort.setParity(SerialPort.NO_PARITY);
        comPort.setNumStopBits(SerialPort.ONE_STOP_BIT);

        WeightSensorListenerContext context = new WeightSensorListenerContext(comPort,code,bean,regex, scpExecutor);

        if(comPort.isOpen()){
            log.info("端口当前是开启状态!");
            SerialPortConnectionCacheService.instance.put(String.valueOf(System.currentTimeMillis()),comPort);
            return;
        }

        // 执行端口连接动作
        if(!comPort.openPort()){
            log.error("打开串口失败,上下文是：{}", JSON.toJSONString(comPort));
            throw new ServiceException("打开串口失败");
        }
        comPort.addDataListener(new WeightSensorListener(context));
        SerialPortConnectionCacheService.instance.put(String.valueOf(System.currentTimeMillis()),comPort);
        log.info("{} Port opened successfully.", port);
    }

    private Properties loadFromDB() {
        ScpSysSettings setting = scpSysSettingsService.findByKey(ScaleConstant.DB_DICT_KEY);
        if (Objects.isNull(setting)) {
            return new Properties();
        }
        Properties prop = JSONObject.parseObject(setting.getSettingValue(), Properties.class);
        return prop;
    }

    public void close() {
        SerialPortConnectionCacheService.closeAll();
    }
}
